home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / XDME / Src / main.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  30KB  |  1,371 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     $Id: main.c 1.2 1994/08/09 15:55:50 digulla Exp digulla $
  5.  
  6.     DESCRIPTION
  7.  
  8.     NOTES
  9.  
  10.     BUGS
  11.  
  12.     TODO
  13.  
  14.     EXAMPLES
  15.  
  16.     SEE ALSO
  17.  
  18.     INDEX
  19.  
  20.     HISTORY
  21.     28. Nov 1992    ada created
  22.     $Log: main.c $
  23.  * Revision 1.2  1994/08/09  15:55:50  digulla
  24.  * removed debug printf
  25.  *
  26.  * Revision 1.1  1994/08/09  13:53:34  digulla
  27.  * Initial revision
  28.  *
  29.  
  30. ******************************************************************************/
  31.  
  32. /**************************************
  33.         Includes
  34. **************************************/
  35. #include "defs.h"
  36. #include <dos/dostags.h>
  37. #include <clib/layers_protos.h>
  38. #include <pragmas/layers_pragmas.h>
  39. #define MYDEBUG     1
  40. #include "debug.h"
  41. //#define DEBUG
  42. //#define DETACH
  43.  
  44.  
  45. /**************************************
  46.         Globale Variable
  47. **************************************/
  48. Prototype int  main      (int, char **);
  49. Prototype void do_tomouse (void);
  50. Prototype void exiterr      (char *);
  51. Prototype int  breakcheck (void);
  52. Prototype void breakreset (void);
  53. Prototype void ops      (char **);
  54. Prototype BOOL loadfile   (BPTR, char *);
  55.  
  56. Prototype struct MsgPort  * Sharedport;
  57. Prototype char            MShowTitle;
  58. Prototype char            noadj;
  59. Prototype struct GfxBase  * GfxBase;
  60. Prototype struct __XDMEArgs XDMEArgs;
  61.  
  62. struct MsgPort * Sharedport;        /* Port for all Windows */
  63. char         MShowTitle;        /* Should DME refresh the title ? */
  64. char         noadj;         /* for blocking software adj. of prop gad
  65.                        when intuition (user) already did it */
  66.  
  67. /* extern struct IntuitionBase * IntuitionBase;
  68. extern struct GfxBase        * GfxBase;
  69. extern struct Library        * IconBase;
  70. extern struct Library        * AslBase; */
  71.  
  72. extern struct Library        * LayersBase;
  73.  
  74. extern long __stack = 16000;
  75.  
  76.  
  77. /**************************************
  78.            Typedefs
  79. **************************************/
  80. typedef struct WBStartup    WBS;
  81. typedef struct DiskObject   DISKOBJ;
  82.  
  83.  
  84. /**************************************
  85.         Interne Variable
  86. **************************************/
  87. static WORD     Mx, My;        /* Mouse-Coords */
  88. static WORD     oMx, oMy;        /* starting coords */
  89. static ULONG     newxdme;        /* force new xdme */
  90.  
  91. static const char default_startupfile[] = ".edrc";
  92. static const char default_projectfile[] = "XDME_Project_File";
  93.  
  94. static const char tmplate[] = "Files/M,"
  95.                   "Startup=-S/K,"
  96.                   "New=-N/S,"
  97.                   "Iconify=-I/S,"
  98.                   "Autoload=-A/S,"
  99.                   "PubScreen=-PS/K,"
  100.                   "ProjectFile=-PF/K";
  101.  
  102. struct __XDMEArgs XDMEArgs =
  103. {
  104.     NULL,        /* Files */
  105.     NULL,        /* Startup-Filename */
  106.     FALSE,        /* NEW */
  107.     FALSE,        /* Iconify */
  108.     FALSE,        /* Autoload */
  109.     NULL,        /* PublicScreen */
  110.     NULL,        /* ProjectFile */
  111.     /* ... */
  112. };
  113.  
  114.  
  115. static const struct Config startup_config =
  116. {
  117.     -1,     /* wwcol */
  118.  
  119.     0, 0,    /* winx, winy           */
  120.     640, 200,    /* winwidth, winheight */
  121.  
  122.     0, 11,    /* iwinx, iwiny */
  123.  
  124.     0, 0,    /* aslleft/top       */
  125.     400, 200,    /* aslwidth/height */
  126.  
  127.     4,        /* tabstop */
  128.     75,     /* margin  */
  129.  
  130.     1,        /* fgpen */
  131.     0,        /* bgpen */
  132.     2,        /* hgpen */
  133.     0,        /* tpen  */
  134.     1,        /* bbpen */
  135.  
  136.     1,        /* insertmode    */
  137.     0,        /* ignorecase    */
  138.     0,        /* wordwrap    */
  139.     0,        /* autosplit    */
  140.     1,        /* autoindent    */
  141.     1,        /* autounblock    */
  142. };
  143.  
  144.  
  145. /**************************************
  146.        Interne Prototypes
  147. **************************************/
  148. extern void __regargs __chkabort (void);
  149.  
  150.  
  151. #ifdef UNUSED
  152. void PrintCWD (void)
  153. {
  154.     static char puffer[256];
  155.     PROC * proc = (PROC *)FindTask (NULL);
  156.  
  157.     NameFromLock (proc->pr_CurrentDir, puffer, sizeof(puffer));
  158.  
  159.     kprintf ("CWD: `%s'\n", puffer);
  160. }
  161. #endif
  162.  
  163.  
  164. int wbmain(WBS * wbs)
  165. {
  166.     return (main (0, (char **)wbs));
  167. } /* wbmain */
  168.  
  169.  
  170. /* disable ^C checking */
  171. void __regargs __chkabort (void) { /* empty */ }
  172.  
  173.  
  174. int main (int mac, char ** mav)
  175. {
  176.     ULONG  nf;            /* # files on command line       */
  177.     BOOL   iawm        = 0; /* overide mouse buttons       */
  178.     BOOL   dontwait    = 0; /* don't wait for a message    */
  179.     BOOL   LeftArea    = 0; /* has mouse after buttonpress moved a certain
  180.                    distance */
  181.     WORD   i;            /* temp. counter           */
  182.     WORD   Code;        /* IDCMP->Code           */
  183.     ULONG  Qualifier;        /* IDCMP->Qualifier        */
  184.     PROC * proc        = (PROC *)FindTask(NULL);   /* our Task    */
  185.     BPTR   origlock;        /* Start-Lock           */
  186.     ULONG  wait_ret;        /* HD Result of Wait       */
  187.     ULONG  Mask        = 0; /* Mask for Wait()             */
  188.     BOOL   gad_active  = 0; /* Is any gadget active ?       */
  189.     UWORD  gad_id;        /* Which one ?           */
  190.     WORD   mqual;        /* Qualifiers for mmove       */
  191.     BOOL   mmove       = 0; /* Mousemove           */
  192.     int    show_cursor;     /* shall I redraw the cursor ? */
  193.  
  194. /*#if MYDEBUG
  195.     D(bug("------------- Hallo, hier ist XDME ----------------\n"));
  196. #endif // */
  197.  
  198. #ifdef DETACH
  199.     /* Detach from CLI */
  200.     fclose (stdin);
  201.     fclose (stdout);        /*  debugging output needs kprintf ! */
  202.     fclose (stderr);        /*  close stderr & console ref. */
  203. #endif
  204.  
  205.     /* cd to dir of shell */
  206.     origlock = CurrentDir (DupLock (proc->pr_CurrentDir));
  207.  
  208.     /* Init lists */
  209.     NewList ((LIST *)&DBase);
  210.     NewList ((LIST *)&PBase);
  211.     init_macros ();
  212.     init_variables ();
  213.     path_init ();
  214.     init_kb ();
  215.  
  216.     /* IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 37L);
  217.     GfxBase      = (struct GfxBase       *)OpenLibrary ("graphics.library",  37L);
  218.     if (!IntuitionBase || !GfxBase)
  219.     exiterr ("cannot open intuition or graphics library");
  220.  
  221.     AslBase = OpenLibrary ("asl.library", 37L); */
  222.     ReqToolsBase = (struct ReqToolsBase *)OpenLibrary ("reqtools.library", 37);
  223.  
  224.     PageJump = 80;        /* 80% of page for Propgad & pageup/down */
  225.  
  226.     String = NULL;        /*    initialize scanf variable   */
  227.  
  228.     ActualBlock.ep = NULL;    /* No block */
  229.  
  230.     /* making a default-ed-config */
  231.     movmem (&startup_config, &default_config, CONFIG_SIZE);
  232.  
  233.     /* setting default flags */
  234.     globalflags.Wdisable = 1;
  235.     globalflags.ActivateToFront = 1;
  236.     globalflags.Windowcycling = 1;
  237.     globalflags.Showtitle = 1;
  238.  
  239.     if (mac == 0)
  240.     {          /*  WORKBENCH STARTUP   */
  241.     globalflags.Wdisable = 0;        /*    allow icon save     */
  242.     Wbs = (WBS *)mav;
  243.  
  244.     /* if (!(IconBase = OpenLibrary ("icon.library", 0)) )
  245.         exiterr ("unable to open icon library"); */
  246.     }
  247.  
  248.     /* Init AREXX */
  249.     mountrequest (0);
  250.     openrexx ();     /*   do this after the last possible call to exiterr() */
  251.     mountrequest (1);
  252.  
  253.     /* Init Keyboard */
  254.     init_structures ();                 /* PATCH_NULL [28 Jan 1993] : added */
  255.     // resethash (currenthash());          /* PATCH_NULL [25 Jan 1993] : added currenthash() */
  256.  
  257.     {
  258.     struct MsgPort * mp;
  259.  
  260.     Forbid ();
  261.     mp = FindPort ("XDME.1");
  262.     Permit ();
  263.  
  264.     newxdme = (!strcmp (RexxPortName, "XDME.1") || !mp);
  265.     }
  266.  
  267.     nf = 0;
  268.     /* Here we have to set the names BEFORE the parsing since none of the
  269.        Arg-Parsers does set them (we make copies later) */
  270.     XDMEArgs.projectfilename = default_projectfile; /* no strdup() here ! */
  271.     XDMEArgs.startupfile     = default_startupfile; /* no strdup() here ! */
  272.  
  273.     /* WB-Startup or CLI ? */
  274.     if (Wbs)
  275.     {
  276.     /* Work on TOOLTypes */
  277.     if (Wbs->sm_ArgList[0].wa_Lock)
  278.     {
  279.         DISKOBJ     * dobj;    /* For WB-Startup */
  280.         struct WBArg * wbarg;
  281.         BPTR       current;
  282.  
  283.         for (i=0; i<Wbs->sm_NumArgs; i++)
  284.         {
  285.         wbarg = &Wbs->sm_ArgList[i];
  286.  
  287.         UnLock (CurrentDir (current = DupLock (wbarg->wa_Lock)));
  288.  
  289.         if (dobj = GetDiskObject (wbarg->wa_Name))
  290.         {
  291.             /* Only process names for ToolTypes, not for the the
  292.                program itself ! */
  293.  
  294.             ops (dobj->do_ToolTypes);
  295.  
  296.             if (i)
  297.             {
  298.             if (loadfile (wbarg->wa_Lock, wbarg->wa_Name))
  299.                 nf ++;
  300.             else
  301.             {
  302.                 FreeDiskObject (dobj);
  303.                 break;
  304.             }
  305.             }
  306.  
  307.             FreeDiskObject (dobj);
  308.         }
  309.         }
  310.  
  311.         /* CD to new base-dir */
  312.         UnLock (CurrentDir (DupLock (Wbs->sm_ArgList[0].wa_Lock)));
  313.     }
  314.     } else
  315.     {
  316.     XDMEArgs.newxdme = newxdme;
  317.  
  318.     /* Parse CLI-args */
  319.     if ((XDMEArgs.ra = ReadArgs (tmplate, (LONG *)&XDMEArgs, NULL))
  320.         && XDMEArgs.files)
  321.     {
  322. #ifdef DEBUG
  323.         UWORD count = 0;
  324. #endif
  325.         char ** nameptr;
  326.  
  327.         for (nameptr=XDMEArgs.files; *nameptr; nameptr ++)
  328.         {
  329. #ifdef DEBUG
  330.         D(bug("Loading %ld %s ...\n", count ++, *nameptr));
  331. #endif
  332.  
  333.         if (loadfile (origlock, *nameptr))
  334.             nf ++;
  335.         else
  336.             break;
  337.         }
  338.     }
  339.     }
  340.  
  341. #ifdef DEBUG
  342.     D(bug("Parsed ARGS\n"));
  343. #endif
  344.  
  345.     if (XDMEArgs.startupfile)
  346.     XDMEArgs.startupfile = strdup (XDMEArgs.startupfile);
  347.     else
  348.     {
  349. #ifdef DEBUG
  350.     D(bug("ERROR: XDMEArgs.startupfile == NULL <<<------------\n"));
  351. #endif
  352.     XDMEArgs.startupfile = strdup (default_startupfile);
  353.     }
  354.  
  355. #ifdef DEBUG
  356.     D(bug("Startup-file : \"%s\"\n", XDMEArgs.startupfile));
  357. #endif
  358.  
  359.     if (XDMEArgs.projectfilename)
  360.     XDMEArgs.projectfilename = strdup (XDMEArgs.projectfilename);
  361.     else
  362.     {
  363. #ifdef DEBUG
  364.     D(bug("ERROR: XDMEArgs.projectfilename == NULL <<<------------\n"));
  365. #endif
  366.     XDMEArgs.projectfilename = strdup (default_projectfile);
  367.     }
  368.  
  369. #ifdef DEBUG
  370.     D(bug("Projectfile : \"%s\"\n", XDMEArgs.projectfilename));
  371. #endif
  372.  
  373.     if (XDMEArgs.publicscreenname)
  374.     XDMEArgs.publicscreenname = strdup (XDMEArgs.publicscreenname);
  375.  
  376. #ifdef DEBUG
  377.     D(bug("Screen : \"%s\"\n", XDMEArgs.publicscreenname ?
  378.         XDMEArgs.publicscreenname : "WBench"));
  379. #endif
  380.  
  381.     /* Free args */
  382.     if (XDMEArgs.ra)
  383.     FreeArgs (XDMEArgs.ra);
  384.  
  385.     if (!nf)
  386.     {  /* no files to edit: Open simple empty window */
  387.     if (XDMEArgs.newxdme || newxdme)
  388.     {
  389.         do_newwindow ();
  390.         if (!Ep)
  391.         goto quit_dme;
  392.  
  393.         if (XDMEArgs.iconify)
  394.         do_iconify ();
  395.     } else
  396.     {
  397.         if (XDMEArgs.iconify)
  398.         {
  399.         do_rexx ("XDME.1", "newwindow iconify");
  400.         } else
  401.         {
  402.         do_rexx ("XDME.1", "newwindow");
  403.         }
  404.     }
  405.     } /* No files */
  406.  
  407.     if (!XDMEArgs.newxdme) /* All done, quit */
  408.     goto quit_dme;
  409.  
  410.     /* Read main .edrc file */
  411.     mountrequest (0);
  412.     av[0] = "source";
  413.     av[1] = (UBYTE *)"s:.edrc";
  414.     do_source (TRUE);   /* Display error */
  415.  
  416.     /* Read other file (if possible) */
  417.     if (NameFromLock (origlock, tmp_buffer, sizeof(tmp_buffer)))
  418.     {
  419.     AddPart (tmp_buffer, XDMEArgs.startupfile, sizeof(tmp_buffer));
  420.     av[1] = tmp_buffer;
  421.     do_source (FALSE); /* Not */
  422.     }
  423.     mountrequest (1);
  424.  
  425.     /* Initialize certain fields in structure */
  426.     {
  427.     ED * ep;
  428.     ED * eb = GetHead ((LIST *)&DBase);
  429.     UWORD ix, iy;
  430.  
  431.     for (ep = eb; ep = GetSucc(&ep->node); )
  432.     {
  433.         ix = ep->beginconfig.iwinx;
  434.         iy = ep->beginconfig.iwiny;
  435.  
  436.         movmem (&eb->beginconfig, &ep->beginconfig, CONFIG_SIZE);
  437.  
  438.         ep->beginconfig.iwinx = ix;
  439.         ep->beginconfig.iwiny = iy;
  440.  
  441.         if (eb->font)
  442.         {
  443.         ep->font = eb->font;
  444.         eb->font->tf_Accessors ++;
  445.         } /* if font */
  446.     } /* for ed */
  447.     }
  448.  
  449.     /* Get Wait()-Mask */
  450.     Mask |= 1 << Sharedport->mp_SigBit;
  451.     wait_ret = 0;
  452.  
  453. loop:
  454.     if (!Ep->iconmode)  /* Display cursor ? */
  455.     text_cursor (1);
  456.  
  457.     for ( ; !globalflags.Quitflag; )
  458.     {
  459.  
  460.     if (!Ep->iconmode)
  461.         window_title ();
  462.  
  463.     if (dontwait)
  464.     {
  465.         dontwait --;
  466.     } else
  467.     {
  468.         /* Wait for Window, AREXX or ^C */
  469.         wait_ret = Wait (Mask | RexxMask | SIGBREAKF_CTRL_C);
  470.     }
  471.  
  472.     show_cursor = 0;    /* don't update cursor */
  473.  
  474.     /*
  475.      *  NOTE: due to operation of breakcheck(), the userport signal
  476.      *  may not be set even if there are messages pending.
  477.      */
  478.     if (wait_ret & RexxMask)          /* HD RexxMessage */
  479.     {
  480.        text_cursor (0);
  481.  
  482.        extern_rexx_command ();       /* process HD rexxcommand */
  483.  
  484.        show_cursor ++;
  485.     }
  486.     else if (wait_ret & SIGBREAKF_CTRL_C)
  487.     {
  488.         globalflags.QuitAll = 1;
  489.         globalflags.Quitflag = 1;
  490.  
  491.         goto boom;
  492.     }
  493.     else if (wait_ret & Mask)              /* HD IntuiMessage */
  494.     {
  495.         IMESS * im;
  496.  
  497.         while (im = (IMESS *)GetMsg(Ep->win->UserPort))
  498.         {
  499.         globalflags.Abortcommand = 0;
  500.         globalflags.Msgchk     = 1;
  501.  
  502.         Code         = im->Code;
  503.         Qualifier    = im->Qualifier;
  504.  
  505.         clearbreaks ();
  506.  
  507.         if (im->IDCMPWindow != Ep->win)
  508.         {
  509.             globalflags.Overide = 0;
  510.  
  511.             if (globalflags.Comlinemode)
  512.             escapecomlinemode ();
  513.  
  514.             text_sync ();
  515.  
  516.             MShowTitle = 0;
  517.  
  518.             if (!Ep->iconmode)
  519.             window_title ();
  520.  
  521.             if (text_switch (im->IDCMPWindow) == 0)
  522.             {
  523.             ReplyMsg ((MSG *)im);
  524.             continue;
  525.             }
  526.         }
  527.  
  528.         Mx = im->MouseX;
  529.         My = im->MouseY;
  530.  
  531.         switch(im->Class)
  532.         {
  533.             case IDCMP_NEWSIZE: {
  534.             struct Window * win = Ep->win;
  535.             WORD        wid;
  536.             WORD        hei;
  537.  
  538.             /* Only works if uniconified */
  539.             if (!Ep->iconmode)
  540.             {
  541.                 /* clear damage list */
  542.                 BeginRefresh (Ep->win);
  543.                 EndRefresh (Ep->win, TRUE);
  544.  
  545.                 /* Leave Comlinemode if neccessary */
  546.                 if (globalflags.Comlinemode)
  547.                 escapecomlinemode ();
  548.  
  549.                 /* Set new window-parameters */
  550.                 set_window_params ();
  551.  
  552.                 /* Erase if neccessary */
  553.                 wid = win->Width - win->BorderRight - 1;
  554.                 hei = win->Height - win->BorderBottom - 1;
  555.  
  556.                 SetAPen (win->RPort, TEXT_BPEN);
  557.                 SetWrMsk (win->RPort, BLOCK_MASK);
  558.  
  559.                 if (wid > Xpixs)
  560.                 {
  561.                 RectFill (win->RPort, Xpixs+1, Ybase,
  562.                     wid, hei);
  563.                 }
  564.  
  565.                 if (hei > Ypixs)
  566.                 {
  567.                 RectFill (win->RPort, Xbase, Ypixs+1,
  568.                     Xpixs, hei);
  569.                 }
  570.  
  571.                 /* Update Text */
  572.                 text_adjust (TRUE);
  573.                 show_cursor ++;
  574.             }
  575.             break; } /* NEWSIZE */
  576.  
  577.             case IDCMP_REFRESHWINDOW:
  578.             if (!Ep->iconmode)
  579.                 OptimizedRefresh (Ep);
  580.  
  581.             break; /* REFRESHWINDOW */
  582.  
  583.             case IDCMP_MOUSEBUTTONS: {
  584.             static WORD   lastCode = 0;
  585.             static ULONG  lastSeconds;
  586.             static ULONG  lastMicros;
  587.             ULONG          Seconds;
  588.             ULONG          Micros;
  589.  
  590.             /* get time of message */
  591.             Seconds = im->Seconds;
  592.             Micros = im->Micros;
  593.  
  594.             /* Avoid Crashing if Window is closed during keyctl() */
  595.             ReplyMsg ((struct Message *)im);
  596.             im = NULL;
  597.  
  598.             switch(Code)
  599.             {
  600.                 case MENUDOWN:
  601.                 if (Ep->iconmode)
  602.                     break;
  603.  
  604.                 case MIDDLEDOWN:
  605.                 case SELECTDOWN:
  606.                 /* if we only activated the window with a
  607.                    buttonpress, ignore it */
  608.                 if (iawm)
  609.                     break;
  610.  
  611.                 /* if there was no click yet or
  612.                    the button changed or this is no
  613.                    double-click anymore, then clear
  614.                    the number of clicks and use the new code */
  615.                 if (!NumClicks          ||
  616.                     lastCode != Code    ||
  617.                     !DoubleClick (lastSeconds, lastMicros,
  618.                         Seconds, Micros))
  619.                 {
  620.                     lastCode    = Code;   /* new code */
  621.                     NumClicks    = 0;      /* button changed */
  622.                 }
  623.  
  624.                 /* remember the time of this click */
  625.                 lastSeconds = Seconds;
  626.                 lastMicros  = Micros;
  627.                 /* increase the number of clicks */
  628.                 NumClicks ++;
  629.  
  630.                 ReportMouse (TRUE, Ep->win);
  631.                 ModifyIDCMP (Ep->win, Ep->win->IDCMPFlags |
  632.                     IDCMP_INTUITICKS);
  633.  
  634.                 oMx = Mx;
  635.                 oMy = My;
  636.                 LeftArea = FALSE;
  637.                 break;
  638.  
  639.                 case SELECTUP:
  640.                 case MENUUP:
  641.                 case MIDDLEUP:
  642.                 ReportMouse (FALSE, Ep->win);
  643.                 ModifyIDCMP (Ep->win, Ep->win->IDCMPFlags &
  644.                     ~IDCMP_INTUITICKS);
  645.                 break;
  646.  
  647.             }
  648.  
  649.             if (Code == MENUDOWN && Ep->iconmode)
  650.             {
  651.                 uniconify ();
  652.                 show_cursor ++;
  653.             } else if (!iawm)
  654.             {
  655. #ifdef NOT_DEF /* PATCH_NULL [15 Feb 1993] : added */
  656.                 if (MacroRecord)
  657.                 {
  658.                 sprintf (tmp_buffer, "setptr %d %d", Mx, My);
  659.                 add_record (tmp_buffer);
  660.                 } /* if */
  661. #endif
  662.                 text_cursor (0);
  663.                 show_cursor ++;
  664. #if 1 /* PATCH_NULL 03-07-94 */
  665.     /* /* WARNING - THESE VALUES MIGHT INTERFERE WITH OTHER KEYS */
  666.                 /* COMMENT:                              */
  667.                 /* Wir sollten noch eine Ueberpruefung der Mausposition einbauen und */
  668.                 /* (unter Beruecksichtigung eines Schwellwertes) bei Mausbewegungen  */
  669.                 /* NumClicks auf 0 resetten, das sollte jedoch jemand machen, der     */
  670.                 /* sich in main auskennt, nicht ich ;-)                 */
  671.                 /* dasselbe ist zu den Qualifiern zu sagen, wenn die sich aendern,     */
  672.                 /* waere es vielleicht geschickter, NumClicks wieder auf 0 zurueck-  */
  673.                 /* zusetzten                             */
  674.                 /* noch besser ware es natuerlich, dieses Verhalten ueber FLAGS zu     */
  675.                 /* regeln, damit alle Seiten zufrieden sind 8-)             */
  676.                 /* oder soll diese Funktionalitaet nach keyctl verlagert werden? ;-) */
  677.                 /* (just my $0.02)                                                   */
  678.                 if ((NumClicks > 1) && (NumClicks < 5))
  679.                 {
  680.                 switch (Code)
  681.                 {
  682.                 case SELECTDOWN: Code = (2 - NumClicks) + 0x67; break;
  683.                 case MIDDLEDOWN: Code = (2 - NumClicks) + 0x64; break;
  684.                 case MENUDOWN:     Code = (2 - NumClicks) + 0x61; break;
  685.     /* /* WARNING - THESE VALUES MIGHT INTERFERE WITH OTHER KEYS */
  686.                 default: ;
  687.                 } /* switch */
  688.                 }
  689.                 else if ((NumClicks > 1) && !(Code & 0x80))
  690.                 NumClicks = 0;
  691. #endif /* PATCH_NULL 03-07-94 */
  692.  
  693.                 keyctl (NULL, Code, Qualifier);
  694.             } else
  695.                 iawm = FALSE;
  696.             break; } /* IDCMP_MOUSEBUTTONS */
  697.  
  698.             case IDCMP_RAWKEY: {
  699.             IMESS    copy;
  700.             ULONG    prevkeys;            /* PATCH_NULL 27-06-94 */
  701.  
  702.             /* Prevent crashing in do_iconify()->
  703.                closesharedwindow */
  704.  
  705.             copy = *im;
  706.             prevkeys = *(ULONG*)im->IAddress;   /* PATCH_NULL 27-06-94 */
  707.             copy.IAddress = &prevkeys;        /* PATCH_NULL 27-06-94 */
  708.  
  709.             ReplyMsg ((struct Message *)im);
  710.             im = NULL;
  711.  
  712.             text_cursor (0);
  713.             show_cursor ++;
  714.             keyctl (©, Code, Qualifier);
  715.             break; } /* IDCMP_RAWKEY */
  716.  
  717.             case IDCMP_MENUPICK: {
  718.             /* PATCH_NULL [02 Apr 1993] : menucontrol like keycontrol >>> */
  719.             IMESS copy;
  720.  
  721.             /* Prevent crashing in do_iconify()-> closesharedwindow */
  722.             copy = *im;
  723.             ReplyMsg ((struct Message *)im);
  724.             im = NULL;
  725.  
  726.             text_cursor (0);
  727.             show_cursor ++;
  728.             menu_cmd (©);
  729.             /* PATCH_NULL [02 Apr 1993] : menucontrol like keycontrol <<< */
  730.             break; } /* IDCMP_MENUPICK */
  731.  
  732.             case IDCMP_CLOSEWINDOW:
  733.             if (globalflags.Comlinemode)
  734.                 escapecomlinemode ();
  735.  
  736.             text_sync ();
  737.             globalflags.Quitflag = TRUE;
  738.             show_cursor = 0;
  739.             break; /* IDCMP_CLOSEWINDOW */
  740.  
  741.             case IDCMP_ACTIVEWINDOW:
  742.             if (!Ep->iconmode)
  743.                 iawm = TRUE;
  744.             break; /* IDCMP_ACTIVEWINDOW */
  745.  
  746.             case IDCMP_MOUSEMOVE:
  747.             if (gad_active)
  748.             {
  749.                 int newtop = new_top ();
  750.  
  751.                 if (newtop != Ep->topline)
  752.                 {
  753.                 noadj = 1;  /* don't touch the damn prop-gadget ! */
  754.                 text_sync ();
  755.  
  756.                 newtop -= Ep->topline;
  757.  
  758.                 text_cursor (0); /* Cursor off */
  759.                 show_cursor ++;
  760.  
  761.                 Ep->line    += newtop;
  762.                 Ep->topline += newtop;
  763.  
  764.                 text_load ();
  765.  
  766.                 scroll_display (0, newtop, 0, Ep->topline,
  767.                     MAXLINELEN, Ep->topline + Lines);
  768.                 }
  769.             }
  770.             else
  771.             {
  772.                 /* Lost ButtonUP ? */
  773.                 if (!(Qualifier & ( IEQUALIFIER_MIDBUTTON |
  774.                         IEQUALIFIER_RBUTTON |
  775.                         IEQUALIFIER_LEFTBUTTON )) )
  776.                 {
  777.                 ReportMouse (FALSE, Ep->win);
  778.                 ModifyIDCMP (Ep->win, Ep->win->IDCMPFlags &
  779.                     ~IDCMP_INTUITICKS);
  780.                 break;
  781.                 }
  782.  
  783.                 /* Process these after all messages have been
  784.                    processed */
  785.                 if (!LeftArea)
  786.                 {
  787.                 if (((Mx > oMx) ? Mx-oMx>4 : oMx-Mx>4) ||
  788.                     ((My > oMy) ? My-oMy>4 : oMy-My>4) )
  789.                     LeftArea = TRUE;
  790.                 }
  791.  
  792.                 if (LeftArea)
  793.                 {
  794.                 mmove = 1;
  795.                 mqual = Qualifier;
  796.                 }
  797.             }
  798.             break; /* IDCMP_MOUSEMOVE */
  799.  
  800.             case IDCMP_GADGETDOWN:
  801.             if (globalflags.Comlinemode)
  802.                 escapecomlinemode ();
  803.  
  804.             gad_id = ((struct Gadget *)im->IAddress)->GadgetID;
  805.  
  806.             if (!gad_id)
  807.             {
  808.                 noadj = 1;      /* block software prop refresh */
  809.             } else
  810.             {
  811.                 text_cursor (0);
  812.                 show_cursor ++;
  813.  
  814.                 if (gad_id == 1)
  815.                 do_scrollup ();
  816.                 else
  817.                 do_scrolldown ();
  818.             }
  819.  
  820.             /* up&down */
  821.             if (gad_id == 1 || gad_id == 2)
  822.                 ModifyIDCMP (Ep->win, Ep->win->IDCMPFlags |
  823.                     IDCMP_INTUITICKS);
  824.             else if (gad_id == 0)  /* scroller */
  825.                 text_adjust (FALSE);
  826.  
  827.             gad_active = TRUE;
  828.             break;
  829.  
  830.             case IDCMP_GADGETUP: {
  831.             gad_id = ((struct Gadget *)im->IAddress)->GadgetID;
  832.  
  833.             switch (gad_id)
  834.             {
  835.             case 0: { /* scroller */
  836.                 int newtop = new_top ();
  837.  
  838.                 if (newtop != Ep->topline)
  839.                 { /* Make sure we don't miss a jump */
  840.                 noadj = 1;  /* don't touch the damn prop-gadget ! */
  841.  
  842.                 text_sync ();
  843.  
  844.                 newtop -= Ep->topline;
  845.  
  846.                 text_cursor (0); /* Cursor off */
  847.                 show_cursor ++;
  848.  
  849.                 Ep->line    += newtop;
  850.                 Ep->topline += newtop;
  851.  
  852.                 text_load ();
  853.  
  854.                 scroll_display (0, newtop, 0, Ep->topline,
  855.                     MAXLINELEN, Ep->topline + Lines);
  856.                 }
  857.                 break; }
  858.  
  859.             case 4: /* zoom */
  860.                 if (!Ep->iconmode)
  861.                 {
  862.                 /* IMESS copy; dead assign */
  863.  
  864.                 /* Prevent crashing in do_iconify()-> closesharedwindow */
  865.                 /* copy = *im; dead assign */
  866.                 ReplyMsg ((struct Message *)im);
  867.                 im = NULL;
  868.  
  869.                 iconify ();
  870.                 }
  871.  
  872.                 break;
  873.  
  874.             default:
  875.                 ModifyIDCMP (Ep->win, Ep->win->IDCMPFlags &
  876.                     ~IDCMP_INTUITICKS);
  877.             }
  878.  
  879.             gad_active = FALSE;
  880.  
  881.             noadj = 0;        /* reallow software prop refresh */
  882.             break; }
  883.  
  884.             case IDCMP_INTUITICKS:
  885.             if (gad_active && gad_id)
  886.             {
  887.                 text_cursor (0);
  888.                 show_cursor ++;
  889.  
  890.                 if (gad_id == 1)
  891.                 do_scrollup ();
  892.                 else
  893.                 do_scrolldown ();
  894.             } else if (LeftArea)
  895.             {
  896.                 mmove = 1;
  897.                 mqual = Qualifier;
  898.             }
  899.             break; /* IDCMP_INTUITICKS */
  900.         } /* switch (class) */
  901.  
  902.         if (im)
  903.             ReplyMsg ((MSG *)im);
  904.  
  905.         if (globalflags.Quitflag)
  906.         {
  907.             dontwait = 2;
  908.             goto boom;
  909.         } /* if (Quitflag) */
  910.         } /* While IntuiMessage */
  911.  
  912.     } /* if (Wait & Mask) */
  913.  
  914.     /* no more iawm */
  915.     iawm = FALSE;
  916.  
  917.     if (mmove && !Ep->iconmode)
  918.     {
  919.         mmove = 0;
  920.  
  921. #ifdef NOT_DEF        /* PATCH_NULL [15 Feb 1993] : added */
  922.         if (MacroRecord) {
  923.         sprintf (tmp_buffer, "setptr %d %d", Mx, My);
  924.         add_record (tmp_buffer);
  925.         } /* if */
  926. #endif
  927.  
  928.         text_cursor (0);
  929.         show_cursor ++;
  930.         keyctl (NULL, QMOVE, mqual);
  931.     } /* if (mmove) */
  932.  
  933.     if (show_cursor && !Ep->iconmode)
  934.         text_cursor (1);
  935.  
  936.     } /* for ( ; !Quitflag; ) */
  937.  
  938. boom:
  939.     text_sync ();
  940.  
  941.     /* Close window(s) */
  942.     {
  943.     WIN          * win;
  944.     struct Gadget * gadget;
  945.     int        result;
  946.  
  947.     do
  948.     {
  949.         if (Ep->modified)
  950.         {
  951.         uniconify ();
  952.         text_cursor (1);
  953.  
  954.         result = getyn ("XDME Warning",
  955.             "The file `%s' has been modified.\n"
  956.             "Do you want to quit anyway (and loose all\n"
  957.             "your work) ?",
  958.             "Quit|Save & Quit|Cancel", Ep->name);
  959.  
  960.         switch (result)
  961.         {
  962.             case 0:
  963.             globalflags.Quitflag = 0;
  964.             goto loop;
  965.             break;
  966.  
  967.             case 2:
  968.             if (!do_save ())
  969.             {
  970.                 globalflags.Quitflag = 0;
  971.                 goto loop;
  972.             }
  973.             break;
  974.         }
  975.         }
  976.  
  977.         win    = Ep->win;
  978.         gadget = Ep->propgad;
  979.  
  980.         rem_prop (Ep);
  981.         text_uninit ();
  982.         closesharedwindow (win);
  983.  
  984.         if (gadget)
  985.         free_prop ((struct PropGadget *)gadget);
  986.     } while (globalflags.QuitAll && Ep);
  987.     }
  988.  
  989.     /* If we have another window left */
  990.     if (Ep)
  991.     {
  992.     globalflags.Quitflag = 0;
  993.  
  994.     if (!Ep->iconmode)
  995.         set_window_params ();
  996.  
  997.     text_load ();
  998.  
  999.     MShowTitle = 0;
  1000.     goto loop;
  1001.     }
  1002.  
  1003. quit_dme:
  1004.     /* Close AREXX */
  1005.     closerexx ();
  1006.  
  1007.     /* Close Port after ARexx */
  1008.     if (Sharedport)
  1009.     {
  1010.     DeletePort (Sharedport);
  1011.     Sharedport = NULL;
  1012.     }
  1013.  
  1014.     /* Free Lock */
  1015.     UnLock (CurrentDir (origlock));
  1016.  
  1017.     /* Free memory */
  1018.     // dealloc_hash (currenthash());        /* PATCH_NULL [25 Jan 1993] : added currenthash */
  1019.     check_stack (NULL);
  1020.  
  1021.     if (XDMEArgs.startupfile)
  1022.     free (XDMEArgs.startupfile);
  1023.  
  1024.     if (XDMEArgs.projectfilename)
  1025.     free (XDMEArgs.projectfilename);
  1026.  
  1027.     if (XDMEArgs.publicscreenname)
  1028.     free (XDMEArgs.publicscreenname);
  1029.  
  1030. #ifdef DEBUG_MEM_H
  1031.     _debug_FreeAllMem ();
  1032. #endif /* DEBUG_MEM_H */
  1033.  
  1034.     clear_record ();
  1035.     exit_menustrips ();
  1036.     exit_keytables ();
  1037.  
  1038.     /* All OK. */
  1039.     exiterr (NULL);
  1040. } /* main */
  1041.  
  1042.  
  1043. Prototype void OptimizedRefresh (ED *);
  1044.  
  1045. void OptimizedRefresh (ED * ep)
  1046. {
  1047.     BOOL old;
  1048.  
  1049.     noadj = 1;    /* don't touch the damn prop-gadget ! */
  1050.  
  1051.     BeginRefresh (ep->win);
  1052.     LockLayer (NULL, ep->win->WLayer);
  1053.     /* text_redisplay ();   Must not be used because it calls RefreshGList() */
  1054.  
  1055.     /* leave Comlinemode */
  1056.     if (old = globalflags.Comlinemode)
  1057.     escapecomlinemode ();
  1058.  
  1059.     /* clear background */
  1060.     SetAPen (ep->win->RPort, 0);
  1061.     RectFill (ep->win->RPort, Xbase,Ybase, Xpixs, Ypixs);
  1062.  
  1063.     redraw_block (TRUE, ep->topline, ep->topcolumn,
  1064.         ep->topline + Lines - 1, ep->topcolumn + Columns - 1);
  1065.  
  1066.     if (old)
  1067.     do_recall ();
  1068.  
  1069.     text_cursor (1);
  1070.  
  1071.     UnlockLayer (ep->win->WLayer);
  1072.     EndRefresh (ep->win, TRUE);
  1073.  
  1074.     noadj = 0;
  1075. } /* OptimizedRefresh */
  1076.  
  1077.  
  1078. void do_tomouse (void)
  1079. {
  1080.     WORD cx, cy;
  1081.     WORD minx, miny, maxx, maxy;
  1082.  
  1083.     if (Columns < 2 || Lines < 2)
  1084.     return;
  1085.  
  1086.     cx = (Mx-Xbase);
  1087.     if (cx >= 0)
  1088.     {
  1089.     if (cx < Xpixs)
  1090.         cx /= Xsize;
  1091.     else
  1092.         cx = Lines;
  1093.     } else
  1094.     cx = -1;
  1095.  
  1096.     cy = (My-Ybase);
  1097.     if (cy >= 0)
  1098.     {
  1099.     if (cy < Ypixs)
  1100.         cy /= Ysize;
  1101.     else
  1102.         cy = Columns;
  1103.     } else
  1104.     cy = -1;
  1105.  
  1106.     minx = 0;            /* Scroll when MOUSE left window */
  1107.     miny = 0;
  1108.     maxx = Columns;
  1109.     maxy = Lines;
  1110.  
  1111.     if (cx < minx)
  1112.     { /* to the left */
  1113.     do_scroll (SCROLL_LEFT);
  1114.  
  1115.     if (cy < miny)
  1116.     { /* Also up */
  1117.         do_scrollup ();
  1118.     } else if (cy >= maxy)
  1119.     { /* also down */
  1120.         do_scrolldown ();
  1121.     }
  1122.     } else if (cx >= maxx)
  1123.     { /* dito to the right */
  1124.     do_scroll (SCROLL_RIGHT);
  1125.  
  1126.     if (cy < miny)
  1127.     {
  1128.         do_scrollup ();
  1129.     } else if (cy >= maxy)
  1130.     {
  1131.         do_scrolldown ();
  1132.     }
  1133.     } else
  1134.     { /* x is ok, check y */
  1135.     if (cy < miny)
  1136.     { /* up */
  1137.         do_scrollup ();
  1138.     } else if (cy >= maxy)
  1139.     { /* down */
  1140.         do_scrolldown ();
  1141.     } else
  1142.         text_position (cx, cy); /* Just reposition cursor */
  1143.     }
  1144. } /* do_tomouse */
  1145.  
  1146.  
  1147. void exiterr (char * str)
  1148. {
  1149.     if (str)
  1150.     {
  1151.     if (Output ())
  1152.     {
  1153.         Write (Output (), str, strlen (str));
  1154.         Write (Output (), "\n", 1);
  1155.     } else
  1156.     {
  1157.         if (IntuitionBase)
  1158.         error (str);
  1159.     }
  1160.     }
  1161.  
  1162.     /* if (IconBase)
  1163.     {
  1164.     CloseLibrary (IconBase);
  1165.     IconBase = NULL;
  1166.     } */
  1167.  
  1168.     if (ReqToolsBase)
  1169.     {
  1170.     if (RFReq)
  1171.     {
  1172.         rtFreeRequest (RFReq);
  1173.  
  1174.         RFReq = NULL;
  1175.     }
  1176.  
  1177.     CloseLibrary ((struct Library *)ReqToolsBase);
  1178.     ReqToolsBase = NULL;
  1179.     }
  1180.  
  1181.     if (AslBase)
  1182.     {
  1183.     if (FReq)
  1184.     {
  1185.         FreeAslRequest (FReq);
  1186.  
  1187.         FReq = NULL;
  1188.     }
  1189.  
  1190.     /*      CloseLibrary (AslBase);
  1191.     AslBase = NULL; */
  1192.     }
  1193.  
  1194.     /* if (GfxBase)
  1195.     {
  1196.     CloseLibrary ((struct Library *)GfxBase);
  1197.     GfxBase = NULL;
  1198.     }
  1199.  
  1200.     if (IntuitionBase)
  1201.     {
  1202.     CloseLibrary ((struct Library *)IntuitionBase);
  1203.     IntuitionBase = NULL;
  1204.     } */
  1205.  
  1206.     if (str)
  1207.     exit (1);
  1208.  
  1209.     exit (0);
  1210. } /* exiterr */
  1211.  
  1212.  
  1213. /*
  1214.  *  Check break by scanning pending messages in the Inputstream for a ^C.
  1215.  *  Msgchk forces a check, else the check is only made if the signal is
  1216.  *  set in the Inputstream (the signal is reset).
  1217.  */
  1218.  
  1219. int breakcheck (void)
  1220. {
  1221.     IMESS    * im;
  1222.     WIN     * win  = Ep->win;
  1223.     struct List * list = &win->UserPort->mp_MsgList;
  1224.  
  1225.     ULONG sigs = SetSignal(0,SIGBREAKF_CTRL_C);                     /* PATCH_NULL [14 Feb 1993] : that mode slows looping not markably down ; PATCH_NULL 20-07-94 clearing ctl-c */
  1226.  
  1227.     if ((sigs & SIGBREAKF_CTRL_C) != 0) {                           /* PATCH_NULL [14 Feb 1993] : These lines are   */
  1228.     globalflags.Abortcommand = 1; /* PATCH_NULL 20-07-94 added */
  1229.     return(1);                                                  /* PATCH_NULL [14 Feb 1993] : intended to allow */
  1230.     }
  1231.     else if (globalflags.Msgchk || (sigs & (1<<win->UserPort->mp_SigBit)))    /* PATCH_NULL [14 Feb 1993] : external breaking */
  1232.     {
  1233.     globalflags.Msgchk = 0;
  1234.     SetSignal (0,1<<win->UserPort->mp_SigBit);
  1235.  
  1236.     im = (IMESS *)list->lh_Head;
  1237.     Forbid();
  1238.  
  1239.     for ( ; im != (IMESS *)&list->lh_Tail;
  1240.         im = (IMESS *)im->ExecMessage.mn_Node.ln_Succ)
  1241.         {
  1242.         if (im->Class == RAWKEY && (im->Qualifier & 0xFB) == 0x08 &&
  1243.         im->Code == CtlC)
  1244.         {
  1245.  
  1246.         Permit ();
  1247. //          SetSignal (SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C); /* PATCH_NULL 20-07-94 commented out */
  1248.         globalflags.Abortcommand = 1; /* PATCH_NULL 20-07-94 added */
  1249.         return (1);
  1250.         }
  1251.     } /* for IMESS */
  1252.  
  1253.     Permit ();
  1254.     }
  1255.  
  1256.     return (0);
  1257. } /* breakcheck */
  1258.  
  1259.  
  1260. void breakreset (void)
  1261. {
  1262.     SetSignal(0, SIGBREAKF_CTRL_C);
  1263. }
  1264.  
  1265.  
  1266. /* Parse WB-ToolTypes */
  1267.  
  1268. void ops (char ** toolarray)
  1269. {
  1270.     char * tooltype;
  1271.  
  1272.     if (tooltype = FindToolType (toolarray, "ICONIFY"))
  1273.     XDMEArgs.iconify = MatchToolValue (tooltype, "YES");
  1274.     else
  1275.     XDMEArgs.iconify = FALSE;
  1276.  
  1277.     if (tooltype = FindToolType (toolarray, "NEW"))
  1278.     XDMEArgs.newxdme = MatchToolValue (tooltype, "YES") | newxdme;
  1279.     else
  1280.     XDMEArgs.newxdme = newxdme;
  1281.  
  1282.     if (tooltype = FindToolType (toolarray, "AUTOLOAD"))
  1283.     XDMEArgs.autoload = MatchToolValue (tooltype, "YES");
  1284.     else
  1285.     XDMEArgs.autoload = FALSE;
  1286.  
  1287.     if (tooltype = FindToolType (toolarray, "PUBSCREEN"))
  1288.     XDMEArgs.publicscreenname = tooltype;    /* no strdup() here ! */
  1289.  
  1290.     if (tooltype = FindToolType (toolarray, "PROJECTFILE"))
  1291.     XDMEArgs.projectfilename = tooltype;   /* no strdup() here ! */
  1292.  
  1293.     if (tooltype = FindToolType (toolarray, "STARTUP"))
  1294.     XDMEArgs.startupfile = tooltype;   /* no strdup() here ! */
  1295.  
  1296. #ifdef DEBUG
  1297.     D(bug("sfile: %s\nnew %ld\niconify %ld\nauto %ld\n"
  1298.         "PSName: `%s'\npf: `%s'\n", XDMEArgs.startupfile,
  1299.         XDMEArgs.newxdme, XDMEArgs.iconify, XDMEArgs.autoload,
  1300.         XDMEArgs.publicscreenname ? XDMEArgs.publicscreenname : "(nul)",
  1301.         XDMEArgs.projectfilename ? XDMEArgs.projectfilename : "(nul)"));
  1302. #endif
  1303. } /* ops */
  1304.  
  1305.  
  1306. BOOL loadfile (BPTR lock, char * name)
  1307. {
  1308.     char buf[512];
  1309.  
  1310.     /* Load project ? */
  1311.     if (!stricmp (name, XDMEArgs.projectfilename))
  1312.     {
  1313.     if (XDMEArgs.newxdme)
  1314.     {
  1315.         return ((BOOL) load_project ());
  1316.     } else
  1317.     {
  1318.         strcpy (buf, "cd `");
  1319.  
  1320.         if (NameFromLock (lock, buf + 4, sizeof (buf) - 4))
  1321.         {
  1322.         strcat (buf, "' projectload");
  1323.  
  1324.         do_rexx ("XDME.1", buf);
  1325.         }
  1326.     }
  1327.     } else
  1328.     {
  1329.     if (XDMEArgs.newxdme)
  1330.     {
  1331.         /* Normal file. Open new window */
  1332.         do_newwindow ();
  1333.         if (!Ep)
  1334.         return (FALSE);
  1335.  
  1336.         /* Load file for editing */
  1337.         av[0] = (UBYTE *)"newfile";
  1338.         av[1] = (UBYTE *)name;
  1339.  
  1340.         UnLock (Ep->dirlock);
  1341.         Ep->dirlock = DupLock (lock);
  1342.  
  1343.         do_edit ();
  1344.  
  1345.         /* Show title */
  1346.         globalflags.MForceTitle = 1;
  1347.         window_title ();
  1348.  
  1349.         if (XDMEArgs.iconify)
  1350.         do_iconify ();
  1351.     } else
  1352.     { /* Use AREXX */
  1353.         strcpy (buf, "newwindow cd `");
  1354.  
  1355.         if (NameFromLock (lock, buf + 14, sizeof (buf) - 14))
  1356.         {
  1357.         sprintf (buf + strlen (buf), "' newfile `%s'%s",
  1358.             name, (XDMEArgs.iconify ? " iconify" : ""));
  1359.         do_rexx ("XDME.1", buf);
  1360.         }
  1361.     }
  1362.     } /* No PROJECTFILE */
  1363.  
  1364.     return (TRUE);
  1365. } /* loadfile */
  1366.  
  1367.  
  1368. /******************************************************************************
  1369. *****  ENDE main.c
  1370. ******************************************************************************/
  1371.